package com.geovis.emergency.spd.controller.pc;


import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.geovis.common.auth.util.AuthUtil;
import com.geovis.common.core.api.Result;
import com.geovis.common.core.constant.SwaggerConstants;
import com.geovis.common.core.controller.BaseController;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillDutyOrgService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillDutyUserService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillExportService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillPlanService;
import com.geovis.emergency.spd.cache.UserCache;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDutyOrg;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDutyUser;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillPlan;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillPlanDetail;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcMessageConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillPlanApprovalDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillPlanSaveDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillPlanUpdateDTO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillPlanDetailUsersVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillPlanVO;
import com.geovis.emergency.spd.entity.system.entity.SystemUser;
import com.geovis.emergency.spd.util.MsgUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 应急预案指挥模块-演练工作方案 前端控制器
 * </p>
 *
 * @author Lonsho
 * @since 2022-06-08
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/pc/drill/plan")
@Api(value = "应急预案指挥模块-演练工作方案", tags = "应急预案指挥模块-演练工作方案")
public class PcDrillPlanController  extends BaseController<IPcDrillPlanService> {
    private final IPcDrillDutyOrgService pcDrillDutyOrgService;
    private final IPcDrillDutyUserService pcDrillDutyUserService;
    private final IPcDrillExportService pcDrillExportService;
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = SwaggerConstants.SAVE_VALUE, notes = SwaggerConstants.SAVE_VALUE)
    @PostMapping({"/save"})
    public Result<PcDrillPlanVO> save(@RequestBody @Validated PcDrillPlanSaveDTO saveDTO) {
        PcDrillPlanVO pcDrillPlanVO=baseService.savePcDrillPlan(saveDTO);
        //发送消息
        MsgUtil.sendDrillMsg(saveDTO.getPcDrillId(), AuthUtil.getCurrentUserId(), PcMessageConstant.TYPE_PLAN_ADD,pcDrillPlanVO.getOrgName()+"方案已提交",pcDrillPlanVO.getOrgName()+"方案已提交",pcDrillPlanVO.getId());
        return Result.ok(pcDrillPlanVO);
    }
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = SwaggerConstants.UPDATE_VALUE, notes = SwaggerConstants.UPDATE_VALUE)
    @PostMapping({"/update"})
    public Result<PcDrillPlanVO> save(@RequestBody @Validated PcDrillPlanUpdateDTO updateDTO) {
        PcDrillPlanVO pcDrillPlanVO=baseService.updatePcDrillPlan(updateDTO);
        MsgUtil.sendDrillMsg(updateDTO.getPcDrillId(),AuthUtil.getCurrentUserId(),PcMessageConstant.TYPE_PLAN_UPDATE,pcDrillPlanVO.getOrgName()+"方案已更新",pcDrillPlanVO.getOrgName()+"方案已更新",pcDrillPlanVO.getId());
        return Result.ok(pcDrillPlanVO);
    }

    @ApiOperation(value = "获取方案可选人员列表")
    @GetMapping({"/getSelectUsers/{drillId}"})
    public Result<List<PcDrillPlanDetailUsersVO>> getSelectUsers(@PathVariable("drillId") String drillId) {
        return Result.ok(baseService.getSelectUsers(drillId));
    }


    @ApiOperationSupport(order = 3)
    @ApiOperation(value = SwaggerConstants.LIST_VALUE, notes = SwaggerConstants.LIST_NOTES)
    @PostMapping({"/getList/{drillId}/{drillDisasterEventId}"})
    public Result<List<PcDrillPlanVO>> getList(
            @PathVariable("drillId") String drillId,
            @PathVariable("drillDisasterEventId") String drillDisasterEventId,
            @RequestParam(required = false) String groupId,
            @RequestParam(required = false) String status) {
        String userGroupId=pcDrillDutyOrgService.getUserGroupId4WorkPlan(drillId);
        return Result.ok(baseService.pcDrillPlanList(drillId,drillDisasterEventId,userGroupId,status));
    }
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "方案提交审批", notes = "方案提交审批接口")
    @PostMapping({"/approve"})
    public Result approve(@Validated @RequestBody PcDrillPlanApprovalDTO approvalDTO) {
        List<PcDrillPlanDetail> pcDrillPlanDetails=baseService.approve(approvalDTO);
        PcDrillPlan pcDrillPlan = baseService.getById(approvalDTO.getDrillPlanId());
        SystemUser systemUser = UserCache.getUserByUserName(pcDrillPlan.getCreateBy());
        if (approvalDTO.getPass()){
            if (ObjectUtil.isNotNull(systemUser)) {
                //通知提交人，方案审核通过
                MsgUtil.pushMsgByUser(PcMessageConstant.TYPE_PLAN_AUDIT_PASS,"方案审核成功","您提交的方案【已过审】",pcDrillPlan.getPcDrillId(),pcDrillPlan.getId(),systemUser.getId());
            }
            //todo 这里任务可能由一个人处理，这里会向一个人重复发消息，要去重一下
            Map<String,List<PcDrillPlanDetail>> pcDrillPlanDetailsMap=pcDrillPlanDetails.stream().collect(Collectors.groupingBy(PcDrillPlanDetail::getPrincipalId));
            pcDrillPlanDetailsMap.keySet().stream().forEach(userId->{
                // 通知移动端，方案已经下发
                List<PcDrillPlanDetail> details=pcDrillPlanDetailsMap.get(userId);
                MsgUtil.pushMsgByUser(PcMessageConstant.TYPE_PLAN_EXE_SIGN,"您有"+details.size()+"条新的任务待处理","您有"+details.size()+"条新的任务待处理",pcDrillPlan.getPcDrillId(),details.get(0).getId(),userId);
            });
        }else {
            if (ObjectUtil.isNotNull(systemUser)){
                //通知提交人，方案退回
                MsgUtil.pushMsgByUser(PcMessageConstant.TYPE_PLAN_AUDIT_BACK,"方案审核不通过","您提交的方案【已退审】,原因："+approvalDTO.getRejectReason(),pcDrillPlan.getPcDrillId(),pcDrillPlan.getId(),systemUser.getId());
            }
        }
        return Result.ok();
    }
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "预案责任", notes = "预案责任")
    @PostMapping({"/dutyContent/{drillId}/{groupId}"})
    public Result<Map> recommend(@PathVariable("drillId") String drillId,@PathVariable("groupId") String groupId){
        String duty = baseService.dutyGroup(drillId, groupId);
        Map<String, String> dutyMap = Maps.newHashMap();
        if (StrUtil.isNotBlank(duty)){
            dutyMap.put("planDuty",duty);
        }else {
            dutyMap.put("planDuty","未匹配到相关预案");
        }
        if(ObjectUtil.isNotEmpty(groupId)){
            PcDrillDutyOrg pcDrillDutyOrg = pcDrillDutyOrgService.getById(groupId);
            if (ObjectUtil.isNotNull(pcDrillDutyOrg) && StrUtil.isNotBlank(pcDrillDutyOrg.getDuty())){
                dutyMap.put("orgName",pcDrillDutyOrg.getOrgName());
                dutyMap.put("orgDuty",pcDrillDutyOrg.getDuty());
            }
        }
        return Result.ok(dutyMap);
    }
}
